package com.zgc.demo.ftzf.controller;

import com.zgc.demo.ftzf.entity.User;
import com.zgc.demo.ftzf.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import static org.springframework.http.MediaType.*;
import static org.springframework.web.reactive.function.server.EntityResponse.fromObject;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;

@RestController
//@RequestMapping("")
public class TestUserController {
    private static volatile int countNumber = 0;

    private synchronized int getCountNumber () {
        return countNumber++;
    }

    /**
     * 临时直接获取，正常的话中间会隔着service层代码
     */
    @Autowired
    private UserRepository userRepository;

    @GetMapping("/s/{userId}")
    public String printString(@PathVariable("userId") Long userId) {
        return String.format("userId: %s", userId);
    }

    @GetMapping("/sync")
    public String printString2() {
        final int countNumber = getCountNumber();
        final String format = String.format("countNumber: %s", countNumber);
        System.out.println(format);
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return format;
    }

    @GetMapping("/async")
    public Mono<String> async() {

        return Mono.fromCallable(() -> {
            int countNumber = getCountNumber();
            final String format = String.format("countNumber: %s", countNumber);
            System.out.println(format);
//            try {
//                Thread.sleep(200L);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            return format;
        }) ;
    }

    @GetMapping("/s")
    public Mono<String> printMono2() {
        return Mono.just(getCountNumber()+"");
    }

    @GetMapping("/m/{userId}")
    public Mono<Long> printMono(@PathVariable("userId") Long userId) {
        return Mono.just(userId);
    }

    @GetMapping("/{userId}")
    public Mono<User> getUser(@PathVariable("userId") Long userId) {
        return userRepository.findById(userId);
    }

    @GetMapping("/v1/spu/detail")
    public Mono<User> findById(Long id){
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        return Mono.just(id)
                .flatMap(x-> Mono.fromCallable(()-> userRepository.findById(1L))
                        .subscribeOn(Schedulers.elastic())) //关键，netty线程不适合用来处理长时间阻塞的任务
                .doOnSuccess(x-> {
                    stopWatch.stop();
                }).block();
    }
}
